package com.zhigh.project.tools;

import org.apache.commons.lang3.StringUtils;

import javax.annotation.Nullable;
import java.util.Objects;
import java.util.function.Supplier;

/**
 * 断言
 */
public final class Assertions {

    private Assertions() {
    }

    public static <E extends Exception> void assertTrue(boolean predict, Supplier<? extends E> exSupplier) throws E {
        if (!predict) throw safeGet(exSupplier);
    }

    public static <E extends Exception> void assertFalse(boolean predict, Supplier<? extends E> exSupplier) throws E {
        assertTrue(!predict, exSupplier);
    }

    public static <T, E extends Exception> void assertEquals(T except, Object o, Supplier<? extends E> exSupplier) throws E {
        assertTrue(Objects.equals(except, o), exSupplier);
    }

    public static <T, E extends Exception> T assertNonnull(T obj, Supplier<? extends E> exSupplier) throws E {
        assertTrue(Objects.nonNull(obj), exSupplier);
        return obj;
    }

    public static <CH extends CharSequence, E extends Exception> CH assertNonBlank(CH ch, Supplier<? extends E> exSupplier) throws E {
        assertTrue(StringUtils.isNotBlank(ch), exSupplier);
        return ch;
    }

    public static <E extends Exception> void assertIsInstanceOf(Class<?> type, @Nullable Object obj, Supplier<? extends E> exSupplier) throws E {
        assertNonnull(type, () -> new AssertableException("Type to check against must not be null"));
        assertTrue(type.isInstance(obj), exSupplier);
    }

    public static <T> T assertNonnull(T obj, String message) {
        assertNonnull(obj, () -> new IllegalArgumentException(message));
        return obj;
    }


    private static <T> T safeGet(Supplier<T> supplier) {
        T t = supplier.get();
        if (Objects.isNull(t)) {
            throw new AssertableException("Getting null from supplier.");
        }

        return t;
    }

}
